﻿
#include "StringOperate.h"

#include "../CommonDef.h"
#include <string.h>

	
dn_namespace_beg

void SplitString( std::string StrSrc ,std::vector<std::string>& Dest ,char Separator )
{
	if( StrSrc.empty() )
		return ;

	std::string::size_type size_pos = 0;
	std::string::size_type size_prev_pos = 0;

	std::string StrTemp;
	while( (size_pos = StrSrc.find_first_of( Separator ,size_pos)) != std::string::npos)
	{
		StrTemp =  StrSrc.substr(size_prev_pos , size_pos-size_prev_pos );

		Dest.push_back(StrTemp);
		StrTemp.clear();
		size_prev_pos =++ size_pos;
	}     

	Dest.push_back(&StrSrc[size_prev_pos]);
};


std::wstring UTF8ToUnicode(const char* Src,size_t SrcLen)
{
	if (Src == NULL) 
	{
		return std::wstring(L"");
	}

	size_t SrcSizeD = SrcLen + 10;          //?

	wchar_t *Des = new wchar_t[SrcSizeD];
	memset(Des, 0, SrcSizeD * sizeof(wchar_t));

	uint32 s = 0;
	uint32 d = 0;
	//bool toomuchbyte = true; //set true to skip error prefix.

	while (s < SrcLen && d < SrcSizeD)
	{
		unsigned char c = Src[s];
		if ((c & 0x80) == 0) 
		{
			Des[d++] += Src[s++];
		} 
		else if((c & 0xE0) == 0xC0)  ///< 110x-xxxx 10xx-xxxx
		{
			wchar_t& WideChar = Des[d++];
			WideChar  = (Src[s + 0] & 0x3F) << 6;
			WideChar |= (Src[s + 1] & 0x3F);

			s += 2;
		}
		else if((c & 0xF0) == 0xE0)  ///< 1110-xxxx 10xx-xxxx 10xx-xxxx
		{
			wchar_t& WideChar = Des[d++];

			WideChar  = (Src[s + 0] & 0x1F) << 12;
			WideChar |= (Src[s + 1] & 0x3F) << 6;
			WideChar |= (Src[s + 2] & 0x3F);

			s += 3;
		} 
		else if((c & 0xF8) == 0xF0)  ///< 1111-0xxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 
		{
			wchar_t& WideChar = Des[d++];

			WideChar  = (Src[s + 0] & 0x0F) << 18;
			WideChar  = (Src[s + 1] & 0x3F) << 12;
			WideChar |= (Src[s + 2] & 0x3F) << 6;
			WideChar |= (Src[s + 3] & 0x3F);

			s += 4;
		} 
		else 
		{
			wchar_t& WideChar = Des[d++]; ///< 1111-10xx 10xx-xxxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 

			WideChar  = (Src[s + 0] & 0x07) << 24;
			WideChar  = (Src[s + 1] & 0x3F) << 18;
			WideChar  = (Src[s + 2] & 0x3F) << 12;
			WideChar |= (Src[s + 3] & 0x3F) << 6;
			WideChar |= (Src[s + 4] & 0x3F);

			s += 5;
		}
	}

	std::wstring Result = std::wstring(Des);
	delete[] Des;
	Des = NULL;

	return Result;
}



std::string UnicodeToUTF8(const wchar_t* WChar, size_t WCharLen)
{
	std::string Temp;

	for(uint32 i=0;i<WCharLen;i++)
	{
		const int SizeD =8;
		char Utf8[SizeD];
		uint32 Len = 0;
		if (WChar[i] < 0x80)
		{  //
			//length = 1;
			Utf8[Len++] = (char)WChar[i];
		}
		else if(WChar[i] < 0x800)
		{//length = 2;

			if (Len + 1 >= SizeD)
				break;

			Utf8[Len++] = (char)(0xc0 | ( WChar[i] >> 6 ));
			Utf8[Len++] = 0x80 | ( WChar[i] & 0x3f );
		}
		else if(WChar[i] < 0x10000 )
		{//length = 3;
			if (Len + 2 >= SizeD)
				break;

			Utf8[Len++] = 0xe0 | ( WChar[i] >> 12 );
			Utf8[Len++] = 0x80 | ( (WChar[i] >> 6) & 0x3f );
			Utf8[Len++] = 0x80 | ( WChar[i] & 0x3f );
		}
		else if( WChar[i] < 0x200000 ) 
		{
			//length = 4;
			if (Len + 3 >= SizeD)
				break;

			Utf8[Len++] = 0xf0 | ( (int)(WChar[i]) >> 18 );
			Utf8[Len++] = 0x80 | ( (WChar[i] >> 12) & 0x3f );
			Utf8[Len++] = 0x80 | ( (WChar[i] >> 6) & 0x3f );
			Utf8[Len++] = 0x80 | ( WChar[i] & 0x3f );
		}

		Utf8[Len] = '\0';

		Temp.append(Utf8);
	}

	return Temp;
}


dn::uint32 GetUTF8StrGrade(const char* str, size_t len)
{
	if (str == 0) return 0;
	dn::uint32 grade = 0;

	size_t s = 0;
	while (s < len )
	{
		unsigned char c = str[s];
		if ((c & 0x80) == 0)  {
			grade += 2;
			s++;
		} else if((c & 0xE0) == 0xC0) {  ///< 110x-xxxx 10xx-xxxx
			grade += 2;
			s += 2;
		} else if((c & 0xF0) == 0xE0){  ///< 1110-xxxx 10xx-xxxx 10xx-xxxx
			grade += 3;
			s += 3;
		} else if((c & 0xF8) == 0xF0){  ///< 1111-0xxx 10xx-xxxx 10xx-xxxx 10xx-xxxx 
			grade += 3;
			s += 4;
		} else {
			grade += 3;
			s += 5;
		}
	}

	return grade;
}



dn_namespace_end